


import java.util.Hashtable;

import state.State;
import tool.Mp3Browser;
import tool.Mp3Handler;
import tool.StringUtils;
import boot.Boot;
import function.ChainMp3;
import function.ChainMp3Impl;
import function.Mp3File;
import function.search.SearchFunction;
import function.stat.LongStore;

public class SearchFunctionImpl implements SearchFunction {

	private Boot midlet;
	private Hashtable index = new Hashtable();
	private String[] filter = null;
	private int mp3Counter = 0;

	public SearchFunctionImpl(Boot crawler) {
		super();
		this.midlet = crawler;
	}

	public SearchFunctionImpl(Boot crawler, String[] aFilter) {
		this(crawler);
		filter = aFilter;
	}

	public void setup() throws Throwable {
		// Setup performance = 1600 ms.
		Mp3Browser browser = new Mp3Browser(midlet, filter);
		browser.browse(new Mp3Handler() {

			public void handleNextMP3(String dir, String mp3) throws Throwable {

				mp3Counter++;
				String key = mp3.substring(0, 2).toLowerCase();
				Mp3File mp3File = new Mp3File(dir, mp3);

				if (!index.containsKey(key)) {
					index.put(key, new ChainMp3Impl(mp3File, null, null));
				} else {
					storeMp3WithPeers(mp3File, key);
				}

				// Treatment of special characters
				if (StringUtils.containsSpecialCharacters(key)) {

					if (!index.containsKey("11")) {
						index.put("11", new ChainMp3Impl(mp3File, null, null));
					} else {
						storeMp3WithPeers(mp3File, "11");
					}
				}

				// Treatment of "the"

				if (key.toLowerCase().startsWith("the ")) {
					String replacingKey = key.substring(4, 6);

					if (!index.containsKey(replacingKey)) {
						index.put(replacingKey, new ChainMp3Impl(mp3File, null,
								null));
					} else {
						storeMp3WithPeers(mp3File, replacingKey);
					}
				}

			}

			private void storeMp3WithPeers(Mp3File mp3File, String key) {
				ChainMp3 newSibling = null;
				ChainMp3 chainCurrent = (ChainMp3) index.get(key);
				boolean stored = false;

				while (!stored) {
					boolean lowerThanCurrent = (chainCurrent.getMp3File()
							.getFilename().toLowerCase().compareTo(
									mp3File.getFilename().toLowerCase()) >= 0);
					// mp3File < current

					if (lowerThanCurrent) {
						newSibling = new ChainMp3Impl(mp3File, chainCurrent
								.getPrevious(), chainCurrent);
						if (chainCurrent.getPrevious() == null) {
							index.remove(key);
							index.put(key, newSibling);
						} else {
							chainCurrent.getPrevious().setNext(newSibling);
						}
						chainCurrent.setPrevious(newSibling);
						stored = true;
					} else if (chainCurrent.getNext() == null) {
						newSibling = new ChainMp3Impl(mp3File, chainCurrent,
								null);
						chainCurrent.setNext(newSibling);
						stored = true;
					}
					chainCurrent = chainCurrent.getNext();
				}
			}

		});
		long collectionVolume = browser.getCollectionVolume();
		LongStore.setValue(LongStore.COLLECTION_VOLUME, collectionVolume);
	}

	public ChainMp3 find(String searchEntry) throws Throwable {
		ChainMp3 rawResult = (ChainMp3) index.get(searchEntry);
		ChainMp3 result = rawResult;

		if (!Boot.state().equals(State.WICKED_KEY_PRESSED)) {
			result = filteredFind(rawResult);
		}
		return result;
	}

	private ChainMp3 filteredFind(ChainMp3 rawResult) {
		// TODO Implement filtered find
//		ChainMp3 result = null;
//		ChainMp3 currentInRaw = rawResult;
//		ChainMp3 currentInResult = result;
//		
//		if (currentInRaw)
//		
//		while (currentInRaw.hasNext()) {
//			
//			result = new ChainMp3Impl(rawResult.getMp3File(), null, null);
//		}
		
		return rawResult;
	}

	public int getMp3Number() {
		return mp3Counter;
	}
}
